import actionTypes from './utils/ActionTypes'
import isPlian from './utils/isPlainObject'

/**
 * 合并reducer 返回一个reducer 
 * @param {*} reducers
 */
export default function combineReducers(reducers) {
    valdateReducers(reducers)
    return function reducer(state = {}, action) {
        const newState = {}
        for (const key in reducers) {
            if (Object.hasOwnProperty.call(reducers, key)) {
                const reducer = reducers[key];
                newState[key] = reducer(state[key], action)
            }
        }
        return newState
    }
}

/**
 * 验证reducers
 * @param {*} reducers
 */
function valdateReducers(reducers) {
    // 对象
    if (Object.prototype.toString.call(reducers) !== '[object Object]') {
        throw new TypeError('reducers must be a object')
    }
    // 平面对象
    if (!isPlian(reducers)) {
        throw new TypeError('reducers must be a plian object')
    }
    // 验证reducer的返回结果是不是undefined
    for (const key in reducers) {
        if (Object.hasOwnProperty.call(reducers, key)) {
            const reducer = reducers[key];
            // 传递一个特殊的type值 
            if (
                reducer(undefined, { type: actionTypes.INIT() }) === undefined ||
                reducer(undefined, { type: actionTypes.UNKNOWN() }) === undefined
            ) {
                throw new TypeError('reducers must be not return undefined')
            }
        }
    }
}

